package com.cpp.server.interceptor;

import com.cpp.common.properties.JwtProperties;
import com.cpp.common.utils.JwtUtil;
import com.cpp.pojo.pojo.User;
import com.cpp.common.constant.JwtClaimsConstant;
import com.cpp.server.context.UserHolder;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.server.HandshakeInterceptor;

import jakarta.servlet.http.HttpServletRequest;
import java.util.Map;

/**
 * WebSocket 握手拦截器，用于校验 JWT token 并设置 Principal
 */
@Component
@Slf4j
public class JwtWebSocketHandshakeInterceptor implements HandshakeInterceptor {

    @Autowired
    private JwtProperties jwtProperties;

    /**
     * 握手前拦截
     */
    @Override
    public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response,
                                   WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception {
        // 只处理 HTTP 请求类型的握手
        if (!(request instanceof ServletServerHttpRequest)) {
            return true; // 非 HTTP 请求，放行
        }

        ServletServerHttpRequest serverRequest = (ServletServerHttpRequest) request;
        HttpServletRequest httpRequest = serverRequest.getServletRequest();

        // 从 URL 参数中获取 token
        String token = httpRequest.getParameter("token");

        if (token == null || token.isEmpty()) {
            log.warn("缺少 WebSocket 认证 token");
            response.setStatusCode(org.springframework.http.HttpStatus.UNAUTHORIZED);
            return false;
        }

        try {
            Claims claims = JwtUtil.parseJWT(jwtProperties.getUserSecretKey(), token);

            // 提取用户信息
            Long id = Long.valueOf(claims.get(JwtClaimsConstant.ID).toString());
            String username = String.valueOf(claims.get(JwtClaimsConstant.USERNAME).toString());
            String role = String.valueOf(claims.get(JwtClaimsConstant.ROLE).toString());
            String imageUrl = String.valueOf(claims.get(JwtClaimsConstant.IMAGE_URL).toString());
            String sex = String.valueOf(claims.get(JwtClaimsConstant.SEX).toString());

            User user = User.builder()
                    .id(id)
                    .username(username)
                    .sex(sex)
                    .imageUrl(imageUrl)
                    .role(role)
                    .build();

            // 将用户信息放入 attributes 供后续使用
            attributes.put("user", user);
            UserHolder.setCurrentUser(user);

            log.info("WebSocket 用户认证成功: {}", user.getUsername());
            return true;

        } catch (Exception ex) {
            log.error("WebSocket token 解析失败", ex);
            response.setStatusCode(org.springframework.http.HttpStatus.UNAUTHORIZED);
            return false;
        }
    }

    /**
     * 握手后执行（无论是否成功）
     */
    @Override
    public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response,
                               WebSocketHandler wsHandler, Exception exception) {
        if (exception != null) {
            log.warn("WebSocket 握手完成但出现异常", exception);
        } else {
            log.info("WebSocket 握手完成");
        }
    }
}